package com.huaao.micropolice.core.service.system.impl;

import java.util.HashSet;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.jboss.logging.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.huaao.micropolice.common.util.CollectionsUtil;
import com.huaao.micropolice.core.common.Constants;
import com.huaao.micropolice.core.common.Context;
import com.huaao.micropolice.core.common.page.Page;
import com.huaao.micropolice.core.common.page.Sort;
import com.huaao.micropolice.core.model.content.Subject;
import com.huaao.micropolice.core.model.system.Button;
import com.huaao.micropolice.core.model.system.Dept;
import com.huaao.micropolice.core.model.system.Menu;
import com.huaao.micropolice.core.model.system.Menu_Dept;
import com.huaao.micropolice.core.model.system.Menu_Subject;
import com.huaao.micropolice.core.model.system.Role;
import com.huaao.micropolice.core.model.system.User;
import com.huaao.micropolice.core.repository.system.ButtonDao;
import com.huaao.micropolice.core.repository.system.DeptDao;
import com.huaao.micropolice.core.repository.system.JobsDao;
import com.huaao.micropolice.core.repository.system.MenuDao;
import com.huaao.micropolice.core.repository.system.MenuDeptDao;
import com.huaao.micropolice.core.repository.system.MenuSubjectDao;
import com.huaao.micropolice.core.repository.system.RoleDao;
import com.huaao.micropolice.core.repository.system.UserDao;
import com.huaao.micropolice.core.service.system.RoleService;

@Service
public class RoleServiceImpl implements RoleService{
	@Autowired
	private RoleDao roleDao;
	@Autowired
	private DeptDao deptDao;
	@Autowired
	private JobsDao jobsDao;
	@Autowired
	private UserDao userDao;
	@Autowired
	private MenuDao menuDao;
	@Autowired
	private ButtonDao buttonDao;
	@Autowired
	private MenuSubjectDao menuSubjectDao;
	@Autowired
	private MenuDeptDao menuDeptDao;
	
	@Override
	public void list(Sort sort, Page page) {
		roleDao.list(sort,page);
	}
	
	@Override
	@Transactional
	public void edit(Role role) {
		Role old = roleDao.load(role.getId());
		Dept dept = deptDao.load(role.getDept().getId());
		old.setMark(role.getMark());
		old.setName(role.getName());
		old.setDept(dept);
		roleDao.update(old);
	}

	@Override
	@Transactional
	public void add(Role role) {
		Dept dept = deptDao.load(role.getDept().getId());
		System.out.println(dept.getId());
		role.setDept(dept);
		roleDao.save(role);
	}

	@Override
	@Transactional
	public void dels(String ...ids) {
		roleDao.deleteById(ids);
	}

	@Override
	public Role load(String id) {
		return roleDao.load(id);
	}

	@Override
	@Transactional
	public void bindJobs(String[] jobIds, String id) {
		Role role = roleDao.load(id);
		role.getJobs().clear();
		for(String jobId : jobIds){
			if(!StringUtils.isBlank(jobId)){
				role.getJobs().add(jobsDao.load(jobId));
			}
		}
		roleDao.save(role);
	}

	@Override
	@Transactional
	public void bindUsers(String id, String[] allUserIds, String[] ckUserIds) {
		Role role = roleDao.load(id);
		
		Set<String> ckUserIdSet = new HashSet<String>();
		CollectionsUtil.copy(ckUserIds, ckUserIdSet);
		
		for(String userId : allUserIds){
			if(!StringUtils.isBlank(userId)){//过滤空ID
				User u = userDao.load(userId);
				if(ckUserIdSet.contains(userId)){//add
					if(!role.getUsers().contains(u)){
						role.getUsers().add(u);
					}
				}else{//remove
					if(role.getUsers().contains(u)){
						role.getUsers().remove(u);
					}
				}
			}
		}
	}
	

	@Override
	@Transactional
	public void bindBtns(String[] ckBtns , String[] allBtns, String id) {
		Role role = roleDao.load(id);
		Set<String> ckBtnsSet = new HashSet<String>();
		CollectionsUtil.copy(ckBtns, ckBtnsSet);
		for(String btnId : allBtns){
			if(!StringUtils.isBlank(btnId)){
				Button btn = buttonDao.load(btnId);
				if(ckBtnsSet.contains(btnId)){//add
					if(!role.getButtons().contains(btn)){
						role.getButtons().add(btn);
					}
				}else{//remove
					if(role.getButtons().contains(btn)){
						role.getButtons().remove(btn);
					}
				}
			}
		}
	}

	@Override
	@Transactional
	public void bindMenu(String[] ckNodes, String id) {
		Role role = roleDao.load(id);
		role.getMenus().clear();
		for(String menuId : ckNodes){
			if(!StringUtils.isBlank(menuId)){
				role.getMenus().add(menuDao.load(menuId));
			}
		}
	}
	
	@Override
	public Set<String> findPermissions(User user) {
		Set<String> perms = new HashSet<String>();
		if(user.getUsername().equals("admin")){
			perms.add("*");
			return perms;
		}
		Set<Role> roles = roleDao.getAllRoleByUser(user);
		
		for(Role role : roles){
			for(Menu menu : role.getMenus()){
				perms.add(menu.getPermission());
			}
			for(Button btn : role.getButtons()){
				perms.add(btn.getPermission());
			}
		}
		return perms;
		
	}
	
	@Override
	public Set<Subject> getSubjects(){
		String menuID = (String) MDC.get(Constants.MENU_ID);
		Set<Subject> subs = new HashSet<Subject>();
		if(!StringUtils.isBlank(menuID)){
			User u = userDao.load(Context.getCurrentUser().getId());
			Set<Role> roles = roleDao.getAllRoleByUser(u);
			Set<Menu_Subject> filter = menuSubjectDao.filter(roles , menuID);
			for(Menu_Subject ms : filter){
				subs.add(ms.getSubject());
			}
		}
		return subs;
	}
	
	@Override
	public Set<Dept> getDepts(){
		String menuID = (String) MDC.get(Constants.MENU_ID);
		Set<Dept> depts = new HashSet<Dept>();
		if(!StringUtils.isBlank(menuID)){
			User u = userDao.load(Context.getCurrentUser().getId());
			Set<Role> roles = roleDao.getAllRoleByUser(u);
			Set<Menu_Dept> filter = menuDeptDao.filter(roles, menuID);
			for(Menu_Dept md : filter){
				depts.add(md.getDept());
			}
		}
		return depts;
	}
}
